/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* MpmProjectTaskFeedbackService
* 项目任务反馈
*
* 修改纪录
* 2021-01-14 版本：1.0 lanjianwei 创建。
* @version 版本：1.0
* @author 作者：lanjianwei
* 创建日期：2021-01-14
*/
package com.topscomm.mpm.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.topscomm.cbo.pojo.CboAttachmentEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboAttachmentService;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.cbo.service.impl.CboAttachmentService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.utils.MessageUtil;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.common.DatacodeCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.mpm.service.IMpmProjectTaskFeedbackService;
import com.topscomm.mpm.service.impl.auto.MpmProjectTaskFeedbackServiceAuto;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;

import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import org.springframework.transaction.annotation.Transactional;

@Service(value = "mpmProjectTaskFeedbackService")
@Scope(value = "singleton")
public class MpmProjectTaskFeedbackService extends MpmProjectTaskFeedbackServiceAuto
		implements IMpmProjectTaskFeedbackService {
	FlowDatacodeCache flowDatacodeCache = new FlowDatacodeCache();
	protected List<Map<String, Object>> flowidList = new ArrayList();
	@Autowired
	private ICboAttachmentService cboAttachmentService;
	@Autowired
	private MpmProjectTaskService mpmProjectTaskService;
	@Autowired
	private MpmProjectService mpmProjectService;
	@Autowired
	private ICboMessageSysService cboMessageSysService;
	@Autowired
	private ICboMessageAppService cboMessageAppService;
	@Autowired
	private DatacodeCache datacodeCache;
	@Autowired
	private ICboUserService cboUserService;
	@Autowired
	private MpmProjectVisitExpertService mpmProjectVisitExpertService;
	@Autowired
	private MpmProjectProductInfoService mpmProjectProductInfoService;

	/**
	 * @author: lanjianwei
	 * @date: 2021-01-14
	 * @param entity
	 * @throws ServiceException
	 * @description:单号生成
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity) {
		super.beforeInsert(entity);
		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
			String docNo = String.valueOf(arrayId[0]);
			docNo = docNo.substring(0, 6) + docNo.substring(9);
			entity.setValue(MpmProjectTaskFeedbackEntity.FieldDocno, docNo);
		}
		if (StringUtil.isEmpty(ConvertUtil.convertToString(entity.getValue("istaskfeedback")))) {
			entity.setValue("istaskfeedback", "1");
		}
		// 为差距与改进、任务反馈赋值submitdate
		entity.setValue("submitdate", new Date());
		// 如果是差距与改进，更新任务的完成时间
		if (MpmSystemConst.TaskFeedback.Gap.equals(ConvertUtil.convertToString(entity.getValue("istaskfeedback")))) {
			mpmProjectTaskService.updateTaskUpdateDate(ConvertUtil.convertToString(entity.getValue("taskid")));
		}
	}

	/**
	 * @author: houyuhang
	 * @date: 2022-06-15
	 * @param entity
	 * @throws ServiceException
	 * @description: 差距与改进新增内容保存后，向任务责任人发送消息
	 * @modify:
	 */
	@Override
	protected void afterInsert(BasicEntity entity) {
		super.afterInsert(entity);
		// 差距与改进,向任务责任人发送消息
		this.sendMessageGap(entity);
	}

	/**
	 * @Title: beforeSubmit
	 * @description:
	 * @param entity
	 * @param sessionUserBean
	 * @author: lanjianwei
	 * @date: 2021年1月15日下午2:52:26
	 * @modify:
	 */
	@Override
	protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		super.beforeSubmit(entity, sessionUserBean);
		MpmProjectTaskFeedbackEntity mpmProjectTaskFeedbackEntity = (MpmProjectTaskFeedbackEntity) entity;
		this.flowidList = flowDatacodeCache.getApprovalFlowListMap("ApprovalFlow_MpmProjectTaskFeedback",
				mpmProjectTaskFeedbackEntity.getApplyusercode(), "sortcode");
		if (flowidList.size() > 0) {// 赋值审批流程id
			mpmProjectTaskFeedbackEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
		} else {
			throw new ServiceException("没有匹配的审批流，请联系管理员！");
		}
		// 判断是否有审批中的单据，有则不让提交
		String taskid = mpmProjectTaskFeedbackEntity.getTaskid();
		long id =mpmProjectTaskFeedbackEntity.getId();
		StringBufferProxy whereSql = new StringBufferProxy();
		whereSql.appendLineSingle(" taskid='{0}' and id != {1} and state = 1", taskid,id);
		List<MpmProjectTaskFeedbackEntity> mpmProjectTaskFeedbackEntities = this.queryByWhere(whereSql.toString());
		if(mpmProjectTaskFeedbackEntities.size()>0) {
			throw new ServiceException("存在仍在审核中的“进度更新”单据，请等待审核完毕后再新增“进度更新”单据！进度详情可点击历史进度查看。");
		}
		// 如果任务反馈进度为100%，且对应的里程碑责任人离职，弹出提示框不允许提交任务反馈
		String taskschedule = mpmProjectTaskFeedbackEntity.getTaskschedule();
		if ("100".equals(taskschedule)) {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" mpmprojecttask.id = '{0}' and mpmprojectmilepost.enabled = 1 and cbouser.enabled = 1 ", taskid);
			List<Map<String, Object>> responseList = this.queryMapByWhere(sql.toString(), "queryMilepostResponse");
			if (responseList.size() == 0) {
				throw new ServiceException("该任务对应的里程碑责任人已离职，请联系项目经理进行变更。");
			}
		}
	}

	/**
	 * @Title: queryFeedbackDetailForTask
	 * @description:为任务查询最新进度细节
	 * @param taskList
	 * @author: zhangjunyao
	 * @date: 2022年3月23日
	 * @modify:
	 */
	protected void queryFeedbackDetailForTask(List<Map<String, Object>> taskList) {
		StringBufferProxy sql = new StringBufferProxy();
		List<String> taskStateList = new ArrayList<>();
		Map<String, Object> sqlMap = new HashMap<>();
		// 只有进行中、已完成、未完成关闭、异常关闭的任务有任务反馈
		taskStateList.add(MpmSystemConst.TaskStateCode.TaskIncompleteCode);
		taskStateList.add(MpmSystemConst.TaskStateCode.TaskCompleteCode);
		taskStateList.add(MpmSystemConst.TaskStateCode.TaskIncompleteCloseCode);
		taskStateList.add(MpmSystemConst.TaskStateCode.TaskCloseCode);
		for (Map<String, Object> task : taskList) {
			String taskState = ConvertUtil.convertToString(task.get(MpmProjectTaskEntity.FieldTaskstate));
			if (taskStateList.contains(taskState)) {
				String taskId = ConvertUtil.convertToString(task.get("id"));
				sql.clear();
				sql.appendSingle(" {0} = '{1}' and state > 0 ", MpmProjectTaskFeedbackEntity.FieldTaskid, taskId);
				sqlMap.put("whereSql", sql.toString());
				List<MpmProjectTaskFeedbackEntity> mpmProjectTaskFeedbackEntities = this.query(sqlMap, "queryFeedbackDetailForTask");
				if (CollectionUtil.isEmpty(mpmProjectTaskFeedbackEntities)) {
					task.put("taskattachments",0);
					continue;
				}
				String ids = mpmProjectTaskFeedbackEntities.stream().map(m->ConvertUtil.convertToString(m.getId())).collect(Collectors.joining("','","'","'"));
				sql.clear();
				sql.appendSingle("sourcetype = '{0}' and sourceid in ({1})",MpmProjectTaskFeedbackEntity.tableName,ids);
				List<CboAttachmentEntity> attachments = cboAttachmentService.queryByWhere(sql.toString());
				task.put(MpmProjectTaskFeedbackEntity.FieldTaskfeedbackdetail, mpmProjectTaskFeedbackEntities.get(0).getTaskfeedbackdetail());
				task.put("taskattachments",attachments.size());
			}
		}
	}
	/**
	 * @Title: sendMessageGap
	 * @description:发送差距与反馈消息
	 * @param entity
	 * @author: houyuhang
	 * @date: 2022年6月15日
	 * @modify:
	 */
	public void sendMessageGap(BasicEntity entity) {
		if ("0".equals(entity.getValue("istaskfeedback"))) {
			MpmProjectTaskEntity mpmProjectTaskEntity = mpmProjectTaskService.queryById(ConvertUtil.convertToString(entity.getValue("taskid")));
			if (ObjectUtil.isEmpty(mpmProjectTaskEntity)) {
				return;
			}
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" projectcode = '{0}' ",mpmProjectTaskEntity.getProjectcode());
			MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
			if (ObjectUtil.isEmpty(mpmProjectEntity)) {
				return;
			}
			StringBufferProxy content = new StringBufferProxy();
			String projectlevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(),"code", "name");
			content.appendSingle("【{0} {1}级 {2}】您所负责的{3}任务，项目经理有了新的要求，请及时查看。", mpmProjectEntity.getProjectcode(), projectlevel, mpmProjectEntity.getProjectname(), mpmProjectTaskEntity.getTaskname());
			Map<String, Object> appMap = MessageUtil.createMessageAppMap(mpmProjectTaskEntity.getResponsiblecode(), "销售项目任务差距与改进提醒", content.toString(), mpmProjectEntity.getId(),
					MpmProjectTaskEntity.tableName, 0);
			Map<String, Object> sysMap = MessageUtil.createMessageSysMap(mpmProjectTaskEntity.getResponsiblecode(), mpmProjectTaskEntity.getResponsible(), "销售项目任务差距与改进提醒", content.toString(),
					mpmProjectEntity.getId(), MpmProjectTaskEntity.tableName);
			cboMessageAppService.insertMap(appMap);
			cboMessageSysService.insertMap(sysMap);
		}
	}
	/**
	 * @Title: sendAttachmentMessage
	 * @description:如果是审查会任务的反馈且任务新增了附件，进行消息提醒
	 * @author: houyuhang
	 * @date: 2022年11月25日
	 * @modify:
	 */
	public void sendAttachmentMessage(MpmProjectTaskFeedbackEntity mpmProjectTaskFeedbackEntity) {
		// 是否为审查会任务
		if (StringUtil.isEmpty(mpmProjectTaskFeedbackEntity.getReviewmeetname())) {
			return;
		}
		// 任务反馈是否新增附件
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" sourcetype = 'MpmProjectTaskFeedback' and sourceid = '{0}' and enabled = 1 ", mpmProjectTaskFeedbackEntity.getId());
		List<CboAttachmentEntity> cboAttachmentEntities = cboAttachmentService.queryByWhere(sql.toString());
		if (CollectionUtil.isEmpty(cboAttachmentEntities)) {
			return;
		}
		sql.clear();
		sql.appendSingle(" enabled = 1 and projectcode = '{0}' ", mpmProjectTaskFeedbackEntity.getProjectcode());
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
		if (ObjectUtil.isEmpty(mpmProjectEntity)) {
			return;
		}
		// 将主表审查会文件是否上传的值置为是
		mpmProjectEntity.setUploaddocument("1");
		mpmProjectService.updateEntity(mpmProjectEntity);
		// 封装消息内容
		String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
		List<Map<String, Object>> appList = new ArrayList<>(), sysList = new ArrayList<>();
		Map<String, Object> appMap = new HashMap<>(), sysMap = new HashMap<>();
		String title = "销售项目审查会文件上传提醒";
		StringBufferProxy content = new StringBufferProxy();
		content.appendSingle("【{0}级项目：{1}】审查会文件已上传到任务附件，请登录销售项目管理系统查看。", projectLevel, mpmProjectEntity.getProjectname());
		// 获取发送人员
		List<String> sendUser = this.queryBidUserForFeedback(mpmProjectEntity);
		if (CollectionUtil.isEmpty(sendUser)) {
			return;
		}
		String sendUserStr = sendUser.stream().collect(Collectors.joining("','","'", "'"));
		sql.clear();
		sql.appendSingle(" enabled = 1 and code in ({0}) ", sendUserStr);
		List<CboUserEntity> cboUserEntities = cboUserService.queryByWhere(sql.toString());
		Map<String, List<CboUserEntity>> cboUserMap = cboUserEntities.stream().collect(Collectors.groupingBy(CboUserEntity::getCode));
		for (String user : sendUser) {
			// app推送
			appMap = MessageUtil.createMessageAppMap(user, title, content.toString(), mpmProjectEntity.getId(),
					MpmProjectTaskEntity.tableName, 0);
			// 系统消息
			sysMap = MessageUtil.createMessageSysMap(user, CollectionUtil.isEmpty(cboUserMap.get(user)) ? "" : cboUserMap.get(user).get(0).getName(), title, content.toString(),
					mpmProjectEntity.getId(), MpmProjectTaskEntity.tableName);
			// 封装
			appList.add(appMap);
			sysList.add(sysMap);
		}
		// 消息批量插入
		cboMessageAppService.insertList(appList);
		cboMessageSysService.insertList(sysList);
	}
	/**
	 * @description:审查会推送人查询
	 * @author: houyuhang
	 * @date: 2022年11月25日
	 * @modify:
	 */
	public List<String> queryBidUserForFeedback(MpmProjectEntity mpmProjectEntity) {
		List<String> userList = new ArrayList<>();
		String projectlevel = mpmProjectEntity.getProjectlevel();
		// A级B级项目增加武志辉，其他项目不需要发送消息
		if (MpmSystemConst.ProjectLevel.A.equals(projectlevel) || MpmSystemConst.ProjectLevel.B.equals(projectlevel)) {
			userList.add("2352");
		} else {
			return userList;
		}
		// 获取产品线，根据产品线进行对应人员赋值
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectid = '" + mpmProjectEntity.getId() + "'");
		List<Map<String, Object>> list = mpmProjectProductInfoService.queryMapByWhere(sql.toString());
		if (!CollectionUtil.isEmpty(list)) {
			String productLineCode = list.stream().filter(item -> !ObjectUtil.isEmpty(item.get("productlinecode"))).map(item -> ConvertUtil.convertToString(item.get("productlinecode"))).collect(Collectors.joining(","));
			if (!StringUtil.isEmpty(productLineCode)) {
				userList.addAll(mpmProjectVisitExpertService.queryUserByProductLine(productLineCode));
			}
		}
		// 对重复人员进行过滤
		return userList.stream().distinct().collect(Collectors.toList());
	}
	/**
	 * @Title: deleteBefore
	 * @description: 任务反馈删除时，级联删除存在的任务反馈附件及审批流程
	 * @param whereSql
	 * @return
	 * @author: houyuhang
	 * @date: 2021年11月12日
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	protected void deleteBefore(String whereSql) {
		super.deleteBefore(whereSql);
		//找到删除的一条或多条任务反馈
		List<MpmProjectTaskFeedbackEntity> mpmProjectTaskFeedbackEntities = this.queryByWhere(whereSql);
		if (CollectionUtil.isEmpty(mpmProjectTaskFeedbackEntities)) {
			return;
		}
		// 如果删除了任务反馈，需要同步删除任务反馈关联的任务反馈附件及审批流程
		String taskStr = mpmProjectTaskFeedbackEntities.stream().filter(item -> MpmSystemConst.TaskFeedback.Feedback.equals(item.getIstaskfeedback())).map(item -> ConvertUtil.convertToString(item.getId())).collect(Collectors.joining(","));
		if (StringUtil.isEmpty(taskStr)) {
			return;
		}
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" sourcetype = '{0}' and sourceid in ({1}) ", MpmProjectTaskFeedbackEntity.tableName, taskStr);
		cboAttachmentService.deleteByWhere(sql.toString());
		// 删除flowins和nodeins表信息
		delCboApprovalInsInfo(MpmProjectTaskFeedbackEntity.tableName, taskStr);
	}
}
